namespace Example {

// Example of Lemon only.

int main(string[] args)
{	var s = new InfixSolverNoFlex();
	s.add_token(InfixSolverNoFlexParser.TokenCode.PAREN_OPEN, null);
	s.add_token(InfixSolverNoFlexParser.TokenCode.NUMBER, new Token("2"));
	s.add_token(InfixSolverNoFlexParser.TokenCode.PLUS, null);
	s.add_token(InfixSolverNoFlexParser.TokenCode.NUMBER, new Token("2"));
	s.add_token(InfixSolverNoFlexParser.TokenCode.PAREN_CLOSE, null);
	s.add_token(InfixSolverNoFlexParser.TokenCode.MUL, null);
	s.add_token(InfixSolverNoFlexParser.TokenCode.NUMBER, new Token("10"));
	s.end();
	stdout.printf("Result = %f\n", s.result);
	return 0;
}

// There are 3 classes needed to Lemon: token_type, extra_argument and start_symbol.
// These classes must be defined in single namespace.
// Different Lemon parser is created for each namespace.
// The token_type class must be inherited from GLib.Object.
[Lemon(token_type = true)]
public class Token : GLib.Object
{	public string value;

	public Token(string value)
	{	this.value = value;
	}
}

// The extra_argument class inherits from autogenerated InfixSolverNoFlexParser.
[	Lemon
	(	extra_argument = true,
		left = "PLUS MINUS",
		left = "MUL DIV"
	)
]
public class InfixSolverNoFlex : InfixSolverNoFlexParser
{	public double result = 0;
}

// The start_symbol class must be inherited from GLib.Object.
// It represents the whole syntactic unit.
[Lemon(start_symbol = true)]
public class TranslationUnit : GLib.Object
{	// We tell, that TranslationUnit is just Expr.
	// Non terminal symbols must appear in CamelCase. Terminals must be CAPITALIZED.
	// The first argument is what is marked with "extra_argument = true".
	// The only instance of it was constructed in main().
	[Lemon(pattern = "Expr(a)")]
	public TranslationUnit(InfixSolverNoFlex solver, Expr a)
	{	solver.result = a.value;
	}
}

// Class representing nonterminal symbol "Expr"
public class Expr : AtomicExpr
{	// Expr can be AtomicExpr
	[Lemon(pattern = "AtomicExpr(a)")]
	public Expr._1(InfixSolverNoFlex solver, AtomicExpr a)
	{	value = a.value;
	}

	// Expr can be sequence of Expr PLUS Expr
	[Lemon(pattern = "Expr(a) PLUS Expr(b)")]
	public Expr._2(InfixSolverNoFlex solver, Expr a, Expr b)
	{	value = a.value + b.value;
	}

	[Lemon(pattern = "Expr(a) MINUS Expr(b)")]
	public Expr._3(InfixSolverNoFlex solver, Expr a, Expr b)
	{	value = a.value - b.value;
	}

	[Lemon(pattern = "Expr(a) MUL Expr(b)")]
	public Expr._4(InfixSolverNoFlex solver, Expr a, Expr b)
	{	value = a.value * b.value;
	}

	[Lemon(pattern = "Expr(a) DIV Expr(b)")]
	public Expr._5(InfixSolverNoFlex solver, Expr a, Expr b)
	{	value = a.value / b.value;
	}
}

// Class representing nonterminal symbol "AtomicExpr"
public class AtomicExpr : GLib.Object
{	public double value;

	// The type of terminal symbol is Token, since it was marked as "token_type = true".
	[Lemon(pattern = "NUMBER(a)")]
	public AtomicExpr._1(InfixSolverNoFlex solver, Token a)
	{	value = double.parse(a.value);
	}

	[Lemon(pattern = "PLUS AtomicExpr(a)")]
	public AtomicExpr._2(InfixSolverNoFlex solver, AtomicExpr a)
	{	value = a.value;
	}

	[Lemon(pattern = "MINUS AtomicExpr(a)")]
	public AtomicExpr._3(InfixSolverNoFlex solver, AtomicExpr a)
	{	value = -a.value;
	}

	// This one is special. Instead of writing constructor for Lemon action,
	// we use a static method that returns an instance of this class (AtomicExpr).
	// This approach is good when there is already instance available, so no need to construct.
	[Lemon(pattern = "PAREN_OPEN Expr(a) PAREN_CLOSE")]
	public static AtomicExpr _4(InfixSolverNoFlex solver, Expr a)
	{	return a as AtomicExpr;
	}
}

} // end namespace
